package com.lowcodeai.user.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.BCrypt;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lowcodeai.common.result.Result;
import com.lowcodeai.user.dto.UserCreateRequest;
import com.lowcodeai.user.dto.UserQueryRequest;
import com.lowcodeai.user.dto.UserUpdateRequest;
import com.lowcodeai.user.entity.UserInfo;
import com.lowcodeai.user.mapper.UserInfoMapper;
import com.lowcodeai.user.service.UserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 用户服务实现类
 * 
 * @author LowCodeAI
 * @since 1.0.0
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {

    private final UserInfoMapper userInfoMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<UserInfo> createUser(UserCreateRequest request) {
        try {
            // 1. 检查用户名是否已存在
            UserInfo existingUser = userInfoMapper.selectByUsername(request.getUsername());
            if (existingUser != null) {
                return Result.error("用户名已存在");
            }

            // 2. 检查邮箱是否已存在
            if (StrUtil.isNotBlank(request.getEmail())) {
                existingUser = userInfoMapper.selectByEmail(request.getEmail());
                if (existingUser != null) {
                    return Result.error("邮箱已存在");
                }
            }

            // 3. 检查手机号是否已存在
            if (StrUtil.isNotBlank(request.getPhone())) {
                existingUser = userInfoMapper.selectByPhone(request.getPhone());
                if (existingUser != null) {
                    return Result.error("手机号已存在");
                }
            }

            // 4. 创建用户
            UserInfo userInfo = new UserInfo();
            userInfo.setUsername(request.getUsername());
            userInfo.setPassword(BCrypt.hashpw(request.getPassword()));
            userInfo.setNickname(request.getNickname());
            userInfo.setEmail(request.getEmail());
            userInfo.setPhone(request.getPhone());
            userInfo.setAvatar(request.getAvatar());
            userInfo.setStatus(request.getStatus());
            userInfo.setTenantId(request.getTenantId());

            userInfoMapper.insert(userInfo);

            // 5. 分配角色（如果有）
            if (request.getRoleIds() != null && !request.getRoleIds().isEmpty()) {
                // 这里需要调用角色分配服务
                // assignRoles(userInfo.getId(), request.getRoleIds());
            }

            log.info("创建用户成功: {}", userInfo.getUsername());
            return Result.success(userInfo);

        } catch (Exception e) {
            log.error("创建用户失败", e);
            return Result.error("创建用户失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<UserInfo> updateUser(UserUpdateRequest request) {
        try {
            // 1. 检查用户是否存在
            UserInfo existingUser = userInfoMapper.selectById(request.getId());
            if (existingUser == null) {
                return Result.error("用户不存在");
            }

            // 2. 检查邮箱是否被其他用户使用
            if (StrUtil.isNotBlank(request.getEmail()) && !request.getEmail().equals(existingUser.getEmail())) {
                UserInfo userWithEmail = userInfoMapper.selectByEmail(request.getEmail());
                if (userWithEmail != null && !userWithEmail.getId().equals(request.getId())) {
                    return Result.error("邮箱已被其他用户使用");
                }
            }

            // 3. 检查手机号是否被其他用户使用
            if (StrUtil.isNotBlank(request.getPhone()) && !request.getPhone().equals(existingUser.getPhone())) {
                UserInfo userWithPhone = userInfoMapper.selectByPhone(request.getPhone());
                if (userWithPhone != null && !userWithPhone.getId().equals(request.getId())) {
                    return Result.error("手机号已被其他用户使用");
                }
            }

            // 4. 更新用户信息
            UserInfo userInfo = new UserInfo();
            userInfo.setId(request.getId());
            userInfo.setNickname(request.getNickname());
            userInfo.setEmail(request.getEmail());
            userInfo.setPhone(request.getPhone());
            userInfo.setAvatar(request.getAvatar());
            if (request.getStatus() != null) {
                userInfo.setStatus(request.getStatus());
            }

            userInfoMapper.updateById(userInfo);

            // 5. 更新角色（如果有）
            if (request.getRoleIds() != null) {
                // 这里需要调用角色分配服务
                // updateUserRoles(request.getId(), request.getRoleIds());
            }

            log.info("更新用户成功: {}", userInfo.getId());
            return Result.success(userInfo);

        } catch (Exception e) {
            log.error("更新用户失败", e);
            return Result.error("更新用户失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Void> deleteUser(Long id) {
        try {
            UserInfo userInfo = userInfoMapper.selectById(id);
            if (userInfo == null) {
                return Result.error("用户不存在");
            }

            userInfoMapper.deleteById(id);

            log.info("删除用户成功: {}", id);
            return Result.success();

        } catch (Exception e) {
            log.error("删除用户失败", e);
            return Result.error("删除用户失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Void> deleteUsers(List<Long> ids) {
        try {
            if (ids == null || ids.isEmpty()) {
                return Result.error("请选择要删除的用户");
            }

            userInfoMapper.deleteBatchIds(ids);

            log.info("批量删除用户成功: {}", ids);
            return Result.success();

        } catch (Exception e) {
            log.error("批量删除用户失败", e);
            return Result.error("批量删除用户失败");
        }
    }

    @Override
    public Result<UserInfo> getUserById(Long id) {
        try {
            UserInfo userInfo = userInfoMapper.selectById(id);
            if (userInfo == null) {
                return Result.error("用户不存在");
            }

            return Result.success(userInfo);

        } catch (Exception e) {
            log.error("获取用户详情失败", e);
            return Result.error("获取用户详情失败");
        }
    }

    @Override
    public Result<IPage<UserInfo>> getUserPage(UserQueryRequest request) {
        try {
            Page<UserInfo> page = new Page<>(request.getPageNum(), request.getPageSize());
            IPage<UserInfo> userPage = userInfoMapper.selectUserPage(page, request.getUsername(),
                    request.getNickname(), request.getEmail(), request.getPhone(),
                    request.getStatus(), request.getTenantId());

            return Result.success(userPage);

        } catch (Exception e) {
            log.error("分页查询用户失败", e);
            return Result.error("分页查询用户失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Void> resetPassword(Long id, String newPassword) {
        try {
            UserInfo userInfo = userInfoMapper.selectById(id);
            if (userInfo == null) {
                return Result.error("用户不存在");
            }

            UserInfo updateUser = new UserInfo();
            updateUser.setId(id);
            updateUser.setPassword(BCrypt.hashpw(newPassword));

            userInfoMapper.updateById(updateUser);

            log.info("重置密码成功: {}", id);
            return Result.success();

        } catch (Exception e) {
            log.error("重置密码失败", e);
            return Result.error("重置密码失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Void> updateUserStatus(Long id, Integer status) {
        try {
            UserInfo userInfo = userInfoMapper.selectById(id);
            if (userInfo == null) {
                return Result.error("用户不存在");
            }

            UserInfo updateUser = new UserInfo();
            updateUser.setId(id);
            updateUser.setStatus(status);

            userInfoMapper.updateById(updateUser);

            log.info("更新用户状态成功: {} -> {}", id, status);
            return Result.success();

        } catch (Exception e) {
            log.error("更新用户状态失败", e);
            return Result.error("更新用户状态失败");
        }
    }

    @Override
    public Result<Boolean> checkUsernameExists(String username) {
        try {
            UserInfo userInfo = userInfoMapper.selectByUsername(username);
            return Result.success(userInfo != null);

        } catch (Exception e) {
            log.error("检查用户名是否存在失败", e);
            return Result.error("检查用户名是否存在失败");
        }
    }

    @Override
    public Result<Boolean> checkEmailExists(String email) {
        try {
            if (StrUtil.isBlank(email)) {
                return Result.success(false);
            }
            UserInfo userInfo = userInfoMapper.selectByEmail(email);
            return Result.success(userInfo != null);

        } catch (Exception e) {
            log.error("检查邮箱是否存在失败", e);
            return Result.error("检查邮箱是否存在失败");
        }
    }

    @Override
    public Result<Boolean> checkPhoneExists(String phone) {
        try {
            if (StrUtil.isBlank(phone)) {
                return Result.success(false);
            }
            UserInfo userInfo = userInfoMapper.selectByPhone(phone);
            return Result.success(userInfo != null);

        } catch (Exception e) {
            log.error("检查手机号是否存在失败", e);
            return Result.error("检查手机号是否存在失败");
        }
    }
} 